import "@stdlib/deploy";
import "@stdlib/ownable";

message InintLeai {
    ad: Address;
    superior: Address;
}

message AddLeaiBalance {
    amount: Int as uint256;
    ad: Address;
}
message Withdrawal {
    amount: Int as uint256;
}

message WithdrawalEvent {
    amount: Int as uint256;
    ad: Address;
}

message JettonAddress {
    jettonAddress: Address; // 地址
    walletjettonAddress: Address; // 来源
    to: Address; // 目标
}

message DevAddress {
    ad: Address;
}

struct LeAIDetails {
    LeAIAddress: Address;
    balance: Int as uint256;
    jettonAddress: Address;
    superior: Address;
    ownAddress:Address;
}

contract LeAIParent with Deployable {

    //
    addressMapBalance: map<Address, Int>;
    own: Address; // 最高权限
    dev: Address; // 开发者权限
    jettonAddress:Address;
    walletjettonAddress:Address;
    toto:Address;

    init(dev:Address,jettonAddress:Address) {
        self.own = sender();
        self.dev = dev;
        self.jettonAddress = jettonAddress;
        self.walletjettonAddress = dev;
        self.toto = dev;
        self.addressMapBalance = emptyMap();
    }

    receive(){

    }

    // 领取此合约的所有ton币
    receive("withdraw all") {
        require(sender() == self.deployer, "Only deployer is allowed to withdraw");
        send(SendParameters{
        to: sender(),
        bounce: true,
        value: 0,
        mode: SendRemainingBalance + SendIgnoreErrors
        });
    }

    //    receive(msg: InintLeai){
    //        self.addressMapBalance.set(sender(),0);
    //        self.reply("init Leai".asComment()); // 剩余 gas 返回给 发送者 ,并传递当前的数量
    //        emit(InintLeai{ad: msg.ad,superior:msg.superior}.toCell());
    //    }

    // 增加用户余额
    receive(msg: AddLeaiBalance) {
        require(self.dev == sender() || self.own == sender(), "You are not dev or own!");
        if(self.addressMapBalance.get(msg.ad) == null) {
            self.addressMapBalance.set(msg.ad,0);
        }
        let amount : Int  =  self.addressMapBalance.get(msg.ad)!!;
        self.addressMapBalance.set(msg.ad,amount + msg.amount);
        self.reply("add LeaiBalance".asComment());
        emit(AddLeaiBalance{amount: msg.amount,ad:msg.ad}.toCell());
    }

    // 设置代币地址
    receive(msg: JettonAddress) {
        require(sender() == self.own, "not own !");
        self.jettonAddress = msg.jettonAddress;
        self.walletjettonAddress = msg.walletjettonAddress;
        self.toto = msg.to;
        self.reply("set jetton address".asComment()); // 剩余 gas 返回给 发送者 ,并传递当前的数量
    }

    // 设置dev地址
    receive(msg: DevAddress) {
        require(sender() == self.own, "not own !");
        self.dev = msg.ad;
        self.reply("set dev address".asComment()); // 剩余 gas 返回给 发送者 ,并传递当前的数量
        emit(DevAddress{ad: msg.ad}.toCell());
    }

    // 用户提现
    receive(msg: Withdrawal) {
        if(self.addressMapBalance.get(sender()) == null) {
            self.addressMapBalance.set(sender(),0);
        }
        let amount : Int  =  self.addressMapBalance.get(sender())!!;
        require(msg.amount <= amount, "Insufficient permissions!");
        self.addressMapBalance.set(sender(),amount - msg.amount);
        // 把代币转移到用户的地址上
        send(SendParameters{
            to: self.jettonAddress,
            value: ton("0.1"),
            bounce: false,
            mode: SendBounceIfActionFail,
            body:
            TokenTransfer{
                queryId: 0,
                amount: msg.amount,
                destination: sender(),
                response_destination: myAddress(),
                custom_payload:  emptyCell(),
                forward_ton_amount: 1,
                forward_payload: "withdrawal".asComment().asSlice()
                }.toCell()
        });
        self.reply("withdrawal".asComment()); // 剩余 gas 返回给 发送者 ,并传递当前的数量
        emit(WithdrawalEvent{amount: msg.amount,ad:sender()}.toCell());
    }

    // 合约地址 地址余额  地址代币 上级地址 合约own
    get fun details(ad:Address): LeAIDetails {
        if(self.addressMapBalance.get(ad) == null) {
            self.addressMapBalance.set(ad,0);
        }
        let amount : Int  =  self.addressMapBalance.get(ad)!!;
        return LeAIDetails{
        LeAIAddress:myAddress(),
        balance:amount,
        jettonAddress: self.jettonAddress,
        superior: newAddress(0,0),
        ownAddress:self.own
        };
    }

    get fun getSend(ad:Address): Address{
        return ad;
    }

    get fun getAmount(ad:Address): Int{
        if(self.addressMapBalance.get(ad) == null) {
            self.addressMapBalance.set(ad,0);
        }
        let amount : Int  =  self.addressMapBalance.get(ad)!!;
        return amount;
    }

    get fun myContractAddress(ad:Address): Address{

        return myAddress();
    }

    get fun myJettonAddress(ad:Address): Address{
        return self.jettonAddress;
    }

    get fun mySuperiorAddress(ad:Address): Address{
        return newAddress(0,0);
    }

    get fun myOwnAddress(ad:Address): Address{
        return self.own;
    }

    get fun toto(ad:Address): Address{
        return self.toto;
    }

    get fun from1(ad:Address): Address{
        return self.walletjettonAddress;
    }
}



message(0xf8a7ea5) TokenTransfer {
    queryId: Int as uint64;
    amount: Int as coins;
    destination: Address;
    response_destination: Address;
    custom_payload: Cell?;
    forward_ton_amount: Int as coins;
    forward_payload: Slice as remaining; // Comment Text message when Transfer the jetton
}
//
//message(0x178d4519) TokenTransferInternal {
//    queryId: Int as uint64;
//    amount: Int as coins;
//    from: Address;
//    response_destination: Address;
//    forward_ton_amount: Int as coins;
//    forward_payload: Slice as remaining; // Comment Text message when Transfer the jetton
//}
//
//message(0x7362d09c) TokenNotification {
//    queryId: Int as uint64;
//    amount: Int as coins;
//    from: Address;
//    forward_payload: Slice as remaining; // Comment Text message when Transfer the jetton
//}
//
//message(0x595f07bc) TokenBurn {
//    queryId: Int as uint64;
//    amount: Int as coins;
//    owner: Address;
//    response_destination: Address;
//}
//
//message(0x7bdd97de) TokenBurnNotification {
//    queryId: Int as uint64;
//    amount: Int as coins;
//    owner: Address;
//    response_destination: Address?;
//}
//
//message(0xd53276db) TokenExcesses {
//    queryId: Int as uint64;
//}
//
//message TokenUpdateContent {
//    content: Cell;
//}
//
//struct JettonData {
//    totalSupply: Int;
//    mintable: Bool;
//    owner: Address;
//    content: Cell;
//    walletCode: Cell;
//}
//
//struct JettonWalletData {
//    balance: Int;
//    owner: Address;
//    master: Address;
//    walletCode: Cell;
//}
//
//
//// ============================================================================================================ //
//@interface("org.ton.jetton.master")
//trait Jetton with Ownable {
//
//    totalSupply: Int; // Already set initially
//    mintable: Bool;
//    owner: Address;
//    content: Cell;
//
//    max_supply: Int; // This is not in the TEP-74 interface
//
//    receive(msg: TokenUpdateContent) {
//        self.requireOwner();                // Allow changing content only by owner
//        self.content = msg.content;         // Update content
//    }
//
//    receive(msg: TokenBurnNotification) {
//        self.requireWallet(msg.owner);                     // Check wallet
//        self.totalSupply = self.totalSupply - msg.amount; // Update supply
//
//        if (msg.response_destination != newAddress(0,0)) { // Cashback
//            send(SendParameters{
//            to: msg.response_destination!!,
//            value: 0,
//            bounce: false,
//            mode: SendRemainingValue + SendIgnoreErrors,
//            body: TokenExcesses{
//            queryId: msg.queryId
//            }.toCell()
//            });
//        }
//    }
//
//    // @to The Address receive the Jetton token after minting
//    // @amount The amount of Jetton token being minted
//    // @response_destination The previous owner address
//    fun mint(to: Address, amount: Int, response_destination: Address) {
//        require(self.totalSupply + amount <= self.max_supply, "The total supply will be overlapping.");
//        self.totalSupply = self.totalSupply + amount; // Update total supply
//
//        let winit: StateInit = self.getJettonWalletInit(to); // Create message
//        send(SendParameters{
//        to: contractAddress(winit),
//        value: 0,
//        bounce: false,
//        mode: SendRemainingValue,
//        body: TokenTransferInternal{
//        queryId: 0,
//        amount: amount,
//        from: myAddress(),
//        response_destination: response_destination,
//        forward_ton_amount: 0,
//        forward_payload: emptySlice()
//        }.toCell(),
//        code: winit.code,
//        data: winit.data
//        });
//    }
//
//    fun requireWallet(owner: Address) {
//        let ctx: Context = context();
//        let winit: StateInit = self.getJettonWalletInit(owner);
//        require(contractAddress(winit) == ctx.sender, "Invalid sender");
//    }
//
//    virtual fun getJettonWalletInit(address: Address): StateInit {
//        return initOf JettonDefaultWallet(myAddress(), address);
//    }
//
//    // ====== Get Methods ====== //
//    get fun get_jetton_data(): JettonData {
//        let code: Cell = self.getJettonWalletInit(myAddress()).code;
//        return JettonData{
//        totalSupply: self.totalSupply,
//        mintable: self.mintable,
//        owner: self.owner,
//        content: self.content,
//        walletCode: code
//        };
//    }
//
//    get fun get_wallet_address(owner: Address): Address {
//        let winit: StateInit = self.getJettonWalletInit(owner);
//        return contractAddress(winit);
//    }
//}
//// ============================================================ //
//@interface("org.ton.jetton.wallet")
//contract JettonDefaultWallet {
//    const minTonsForStorage: Int = ton("0.01");
//    const gasConsumption: Int = ton("0.01");
//
//    balance: Int;
//    owner: Address;
//    master: Address;
//
//    init(master: Address, owner: Address) {
//        self.balance = 0;
//        self.owner = owner;
//        self.master = master;
//    }
//
//    receive(msg: TokenTransfer) { // 0xf8a7ea5
//        let ctx: Context = context(); // Check sender
//        require(ctx.sender == self.owner, "Invalid sender");
//
//        // Gas checks
//        let fwdFee: Int = ctx.readForwardFee() + ctx.readForwardFee();
//        let final: Int =  2 * self.gasConsumption + self.minTonsForStorage + fwdFee;
//        require(ctx.value > min(final, ton("0.01")), "Invalid value!!");
//
//        // Update balance
//        self.balance = self.balance - msg.amount;
//        require(self.balance >= 0, "Invalid balance");
//
//        let init: StateInit = initOf JettonDefaultWallet(self.master, msg.destination);
//        let walletAddress: Address = contractAddress(init);
//        send(SendParameters{
//        to: walletAddress,
//        value: 0,
//        mode: SendRemainingValue,
//        bounce: false,
//        body: TokenTransferInternal{
//        queryId: msg.queryId,
//        amount: msg.amount,
//        from: self.owner,
//        response_destination: msg.response_destination,
//        forward_ton_amount: msg.forward_ton_amount,
//        forward_payload: msg.forward_payload
//        }.toCell(),
//        code: init.code,
//        data: init.data
//        });
//    }
//
//    receive(msg: TokenTransferInternal) { // 0x178d4519
//        let ctx: Context = context();
//
//        if (ctx.sender != self.master) {
//            let sinit: StateInit = initOf JettonDefaultWallet(self.master, msg.from);
//            require(contractAddress(sinit) == ctx.sender, "Invalid sender!");
//        }
//
//        // Update balance
//        self.balance = self.balance + msg.amount;
//        require(self.balance >= 0, "Invalid balance");
//
//        // Get value for gas
//        let msgValue: Int = self.msgValue(ctx.value);
//        let fwdFee: Int = ctx.readForwardFee();
//        msgValue = msgValue - msg.forward_ton_amount - fwdFee;
//
//        // 0x7362d09c - notify the new owner of JettonToken that the transfer is complete
//        if (msg.forward_ton_amount > 0) {
//            send(SendParameters{
//            to: self.owner,
//            value: msg.forward_ton_amount,
//            mode: SendPayGasSeparately + SendIgnoreErrors,
//            bounce: false,
//            body: TokenNotification {
//            queryId: msg.queryId,
//            amount: msg.amount,
//            from: msg.from,
//            forward_payload: msg.forward_payload
//            }.toCell()
//            });
//        }
//
//        // 0xd53276db -- Cashback to the original Sender
//        if (msg.response_destination != newAddress(0,0)) {
//            send(SendParameters {
//            to: msg.response_destination,
//            value: msgValue,
//            bounce: false,
//            body: TokenExcesses {
//            queryId: msg.queryId
//            }.toCell(),
//            mode: SendIgnoreErrors
//            });
//        }
//    }
//
//    receive(msg: TokenBurn) {
//        let ctx: Context = context();
//        require(ctx.sender == self.owner, "Invalid sender");  // Check sender
//
//        self.balance = self.balance - msg.amount; // Update balance
//        require(self.balance >= 0, "Invalid balance");
//
//        let fwdFee: Int = ctx.readForwardFee(); // Gas checks
//        require(ctx.value > fwdFee + 2 * self.gasConsumption + self.minTonsForStorage, "Invalid value - Burn");
//
//        // Burn tokens
//        send(SendParameters{
//        to: self.master,
//        value: 0,
//        mode: SendRemainingValue,
//        bounce: true,
//        body: TokenBurnNotification{
//        queryId: msg.queryId,
//        amount: msg.amount,
//        owner: self.owner,
//        response_destination: self.owner
//        }.toCell()
//        });
//    }
//
//    get fun msgValue(value: Int): Int {
//        let msgValue: Int = value;
//        let tonBalanceBeforeMsg: Int = myBalance() - msgValue;
//        let storageFee: Int = self.minTonsForStorage - min(tonBalanceBeforeMsg, self.minTonsForStorage);
//        msgValue = msgValue - (storageFee + self.gasConsumption);
//        return msgValue;
//    }
//
//    bounced(src: bounced<TokenTransferInternal>) {
//        self.balance = self.balance + src.amount;
//    }
//
//    bounced(src: bounced<TokenBurnNotification>) {
//        self.balance = self.balance + src.amount;
//    }
//
//    get fun get_wallet_data(): JettonWalletData {
//        return JettonWalletData{
//        balance: self.balance,
//        owner: self.owner,
//        master: self.master,
//        walletCode: (initOf JettonDefaultWallet(self.master, self.owner)).code
//        };
//    }
//}

